home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 34.zip / BS1 part 34 / FredFish PD 307.adf / Samp / SAMP.doc < prev    next >
Text File  |  1990-01-13  |  55KB  |  1,174 lines

  1.                        IFF FORM "SAMP" Sampled Sound
  2.  
  3.  Date:   Dec 3,1989
  4.  From:   Jim Fiore and Jeff Glatt, dissidents
  5.  Status: Finally under consideration by CATS thanks to Darius
  6.  
  7.    The form "SAMP" is a file format used to store sampled sound data in some
  8. ways like the current standard, "8SVX". Unlike "8SVX", this new format is not
  9. restricted to 8 bit sample data. There can be more than one waveform per
  10. octave, and the lengths of different waveforms do not have to be factors of
  11. 2. In fact, the lengths (waveform size) and playback mapping (which musical
  12. notes each waveform will "play") are independently determined for each wave-
  13. form. Furthermore, this format takes into account the MIDI sample dump stan-
  14. dard (the defacto standard for musical sample storage), while also incorpo-
  15. rating the ability to store Amiga specific info (for example, the sample data
  16. that might be sent to an audio channel which is modulating another channel).
  17. Although this form can be used to store "sound effects" (typically oneShot
  18. sounds played at a set pitch), it is primarily intended to correct the many
  19. deficiencies of the "8SVX" form in regards to musical sampling. Because the
  20. emphasis is on musical sampling, this format relies on the MIDI (Musical
  21. Instrument Digital Interface) method of describing "sound events" as does
  22. virtually all currently manufactured, musical samplers. In addition, it at-
  23. tempts to incorporate features found on many professional music samplers, in
  24. anticipation that future Amiga models will implement 16 bit sampling, and
  25. thus be able to achieve this level of performance. Because this format is 
  26. more complex than "8SVX", programming examples to demonstrate the use of this
  27. format have been included in both C and assembly. Also, a library of func-
  28. tions to read and write SAMP files is available, with example applications.
  29.  
  30.   SEMANTICS: When MIDI literature talks about a sample, usually it means a
  31. collection of many sample points that make up what we call a "wave".
  32.  
  33.  
  34.         =====SIMILARITIES AND DIFFERENCES FROM THE "8SVX" FORM=======
  35.  
  36.    Like "8SVX", this new format uses headers to separate the various sections
  37. of the sound file into chunks. Some of the chunks are exactly the same since
  38. there wasn't a need to improve them. The chunks that remain unchanged are as
  39. follows:
  40.  
  41.    "(c) "
  42.    "AUTH"
  43.    "ANNO"
  44.  
  45.   Since these properties are all described in the original "8SVX" document,
  46. please refer to that for a description of these chunks and their uses. Like
  47. the "8SVX" form, none of these chunks are required to be in a sound file.
  48. If they do appear, they must be padded out to an even number of bytes.
  49.  
  50.   Furthermore, two "8SVX" chunks no longer exist as they have been incorpo-
  51. rated into the "BODY" chunk. They are:
  52.  
  53.    "ATAK"
  54.    "RLSE"
  55.  
  56.   Since each wave can be completely different than the other waves in the 
  57. sound file (one wave might be middle C on a piano, and another might be a
  58. snare drum hit), it is necessary for each wave to have its own envelope de-
  59. scription, and name.
  60.  
  61.   The major changes from the "8SVX" format are in the "MHDR", "NAME", and
  62. "BODY" chunks.
  63.  
  64.  
  65.           =================THE "SAMP" HEADER================
  66.  
  67.  At the very beginning of a sound file is the "SAMP" header. This is used to
  68. determine if the disk file is indeed a SAMP sound file. It's attributes are
  69. as follows:
  70.  
  71. #define ID_SAMP MakeID('S','A','M','P')
  72.  
  73.   In assembly, this looks like:
  74.  
  75.       CNOP 0,2  ;word-align
  76.  
  77. SAMP         dc.b  'SAMP'
  78. sizeOfChunks dc.l  [sizes of all subsequent chunks summed]
  79.  
  80.  
  81.              =================THE "MHDR" CHUNK=================
  82.  
  83.   The required "MHDR" chunk immediately follows the "SAMP" header and consists
  84. of the following components:
  85.  
  86. #define ID_MHDR MakeID('M','H','D','R')
  87.  
  88.   /* MHDR size is dependant on the size of the imbedded PlayMap. */
  89.  
  90.   typedef struct{
  91.    UBYTE NumOfWaves,      /* The number of waves in this file */
  92.      Format,              /* # of ORIGINAL significant bits from 8-28 */
  93.      Flags,               /* Various bits indicate various functions */
  94.      PlayMode,            /* determines play MODE of the PlayMap */
  95.      NumOfChans,
  96.      Pad,
  97.      PlayMap[128*4],  /* a map of which wave numbers to use for
  98.                           each of 128 possible Midi Notes. Default to 4 */
  99.    } MHDRChunk;
  100.  
  101.    The PlayMap is an array of bytes representing wave numbers. There can be a
  102. total of 255 waves in a "SAMP" file. They are numbered from 1 to 255. A wave
  103. number of 0 is reserved to indicate "NO WAVE". The Midi Spec 1.0 designates
  104. that there are 128 possible note numbers (pitches), 0 to 127. The size of an
  105. MHDR's PlayMap is determined by (NumOfChans * 128). For example, if NumOfChans
  106. = 4, then an MHDR's PlayMap is 512 bytes. There are 4 bytes in the PlayMap
  107. for EACH of the 128 Midi Note numbers. For example, the first 4 bytes
  108. in PlayMap pertain to Midi Note #0. Of those 4 bytes, the first byte is the
  109. wave number to play back on Amiga audio channel 0. The second byte is the
  110. wave number to play back on Amiga audio channel 1, etc. In this way, a single
  111. Midi Note Number could simultaneously trigger a sound event on each of the 4
  112. Amiga audio channels. If NumOfChans is 1, then the PlayMap is 128 bytes and
  113. each midi note has only 1 byte in the PlayMap. The first byte pertains to midi
  114. note #0, the second pertains to midi note #1, etc. In this case, a player
  115. program might elect to simply play back the PlayMap wave number on any
  116. available amiga audio channel. If NumOfChans = 0, then there is no imbedded
  117. PlayMap in the MHDR, no midi note assignments for the waves, and an application
  118. should play back waves on any channel at their default sampleRates.
  119.   In effect, the purpose of the PlayMap array is to determine which (if any)
  120. waves are to be played back for each of the 128 possible Midi Note Numbers.
  121. Usually, the MHDR's NumOfChans will be set to 4 since the Amiga has 4 audio
  122. channels. For the rest of this document, the NumOfChans is assumed to be 4.
  123.   As mentioned, there can be a total of 255 waves in a "SAMP" file, numbered
  124. from 1 to 255. A PlayMap wave number of 0 is reserved to indicate that NO WAVE
  125. number should be played back. Consider the following example:
  126.  
  127.   The first 4 bytes of PlayMap are  1,3,0,200.
  128.  
  129.   If a sample playing program receives (from the serial port or another task
  130. perhaps) Midi Note Number 0, the following should occur:
  131.  
  132.   1) The sampler plays back wave 1 on Amiga audio channel
  133.      number 0 (because the first PlayMap byte is 1).
  134.   2) The sampler plays back wave 3 on Amiga audio channel
  135.      number 1 (because the second PlayMap byte is 3).
  136.   3) The sampler does not effect Amiga audio channel 2 in
  137.      any way (because the third PlayMap byte is a 0).
  138.   4) The sampler plays back wave 200 on Amiga audio channel
  139.      number 4 (because the fourth PlayMap byte is 200).
  140.  
  141.  (This assumes INDEPENDANT CHANNEL play MODE to be discussed later in this
  142.   document.)
  143.  
  144.    All four of the PlayMap bytes could even be the same wave number. This would
  145. cause that wave to be output of all 4 Amiga channels simultaneously.
  146.  
  147.   NumOfWaves is simply the number of waves in the sound file.
  148.  
  149.   Format is the number of significant bits in every sample of a wave.
  150. For example, if Format = 8, then this means that the sample data is an
  151. 8 bit format, and that every sample of the wave can be expressed by a single
  152. BYTE. (A 16 bit sample would need a WORD for every sample point).
  153.  
  154.   Each bit of the Flags byte, when set, means the following:
  155.  
  156. Bit #0 - File continued on another disc. This might occur if the SAMP file
  157.          was too large to fit on 1 floppy. The accepted practice (as incor-
  158.          porated by Yamaha's TX sampler and Casio's FZ-1 for example) is to
  159.          dump as much as possible onto one disc and set a flag to indicate
  160.          that more is on another disc's file. The name of the files must
  161.          be the related. The continuation file should have its own SAMP header
  162.          MHDR, and BODY chunks. This file could even have its continuation
  163.          bit set, etc. Never chop a sample wave in half. Always close the
  164.          file on 1 disc after the last wave which can be completely saved.
  165.          Resume with the next wave within the BODY of the continuation file.
  166.          Also, the NumOfWaves in each file's BODY should be the number saved
  167.          on that disc (not the total number in all combined disk files).
  168.          See the end of this document for filename conventions.
  169.  
  170.   In C, here is how the PlayMap is used when receiving a midi note-on event:
  171.  
  172.   MapOffset = (UBYTE) MidiNoteNumber * numOfChans;
  173.   /* MidiNoteNumber is the received note number (i.e. the second byte of a
  174.      midi note-on event. numOfChans is from the SAMP MHDR. */
  175.   chan0waveNum = (UBYTE) playMap[MapOffset];
  176.   chan1waveNum = (UBYTE) playMap[MapOffset+1];
  177.   chan2waveNum = (UBYTE) playMap[MapOffset+2];
  178.   chan3waveNum = (UBYTE) playMap[MapOffset+3];
  179.  
  180.   if (chan0waveNum != 0)
  181.   { /* get the pointer to wave #1's data, determine the values
  182.        that need to be passed to the audio device, and play this
  183.        wave on Amiga audio channel #0 (if INDEPENDANT PlayMode) */
  184.   }
  185.  
  186.    /* do the same with the other 3 channel's wave numbers */
  187.  
  188.   In assembly, the "MHDR" structure looks like this:
  189.  
  190.              CNOP 0,2
  191. MHDR        dc.b 'MHDR'
  192. sizeOfMHDR  dc.l [this is 6 + (NumOfChans * 128) ]
  193. NumOfWaves  dc.b [a byte count of the # of waves in the file]
  194. Format      dc.b [a byte count of the # of significant bits in a sample point]
  195. Flags       dc.b [bit mask]
  196. PlayMode    dc.b [play MODE discussed later]
  197. NumOfChans  dc.b [# of bytes per midi note for PlayMap]
  198. PlayMap     ds.b [128 x NumOfChans bytes of initialized values]
  199.  
  200.    and a received MidiNoteNumber is interpreted as follows:
  201.  
  202.    moveq   #0,d0
  203.    move.b  MidiNoteNumber,d0  ;this is the received midi note #
  204.    bmi.s   Illegal_Number     ;exit, as this is an illegal midi note #
  205.    moveq   #0,d1
  206.    move.b  NumOfChans,d1
  207.    mulu.w  d1,d0              ;MidiNoteNumber x NumOfChans
  208.    lea     PlayMap,a0
  209.    adda.l  d0,a0
  210.    move.b  (a0)+,chan0waveNum
  211.    move.b  (a0)+,chan1waveNum
  212.    move.b  (a0)+,chan2waveNum
  213.    move.b  (a0),chan3waveNum
  214.  
  215.       tst.b   chan0waveNum
  216.       beq.s   Chan1
  217.  ;Now get the address of this wave number's sample data, determine the
  218.  ;values that need to be passed to the audio device, and output the wave's
  219.  ;data on Amiga chan 0 (assuming INDEPENDANT PlayMode).
  220.  
  221. Chan1 tst.b chan1waveNum
  222.       beq.s Chan2
  223.  ;do the same for the other wave numbers, etc.
  224.  
  225.  
  226.     =====================THE "NAME" CHUNK=========================
  227.  
  228.   #define ID_NAME MakeID('N','A','M','E')
  229.  
  230.   If a NAME chunk is included in the file, then EVERY wave must have a name.
  231. Each name is NULL-terminated. The first name is for the first wave, and it
  232. is immediately followed by the second wave's name, etc. It is legal for a
  233. wave's name to be simply a NULL byte. For example, if a file contained 4
  234. waves and a name chunk, the chunk might look like this:
  235.  
  236.            CNOP 0,2
  237.  
  238. Name       dc.b 'NAME'
  239. sizeOfName dc.l 30
  240.            dc.b 'Snare Drum',0  ;wave 1
  241.            dc.b 'Piano 1',0     ;wave 2
  242.            dc.b 'Piano A4',0    ;wave 3
  243.            dc.b 0               ;wave 4
  244.            dc.b 0
  245.  
  246.   NAME chunks should ALWAYS be padded out to an even number of bytes. (Hence
  247. the extra NULL byte in this example). The chunk's size should ALWAYS be even
  248. consequently. DO NOT USE the typical IFF method of padding a chunk out to an
  249. even number of bytes, but allowing an odd number size in the header.
  250.  
  251.  
  252.             ==============THE "BODY" CHUNK===============
  253.  
  254.  The "BODY" chunk is CONSIDERABLY different than the "8SVX" form. Like all
  255. chunks it has an ID.
  256.  
  257.    #define ID_BODY MakeID('B','O','D','Y')
  258.  
  259. Every wave has an 80 byte waveHeader, followed by its data. The waveHeader
  260. structure is as follows:
  261.  
  262.  typedef struct {
  263.    ULONG  WaveSize;        /* total # of BYTES in the wave (MUST be even) */
  264.    UWORD  MidiSampNum;     /* ONLY USED for Midi Dumps */
  265.    UBYTE  LoopType,        /* ONLY USED for Midi Dumps */
  266.    InsType;         /* Used for searching for a certain instrument */
  267.    ULONG  Period,    /* in nanoseconds at original pitch */
  268.    Rate,             /* # of samples per second at original pitch */
  269.    LoopStart,         /* an offset in BYTES (from the beginning of the
  270.                               of the wave) where the looping portion of the
  271.                               wave begins. Set to WaveSize if no loop. */
  272.    LoopEnd;           /* an offset in BYTES (from the beginning of the
  273.                               of the wave) where the looping portion of the
  274.                               wave ends. Set to WaveSize if no loop. */
  275.    UBYTE  RootNote,        /* the Midi Note # that plays back original pitch */
  276.    VelStart;            /* 0 = NO velocity effect, 128 =
  277.                                 negative direction, 64 = positive
  278.                                 direction (it must be one of these 3) */
  279.    UWORD VelTable[16];  /* contains 16 successive offset values
  280.                                 in BYTES from the beginning of the wave */
  281.  
  282.   /* The ATAK and RLSE segments contain an EGPoint[] piece-wise
  283.      linear envelope just like 8SVX. The structure of an EGPoint[]
  284.      is the same as 8SVX. See that document for details. */
  285.  
  286.    ULONG  ATAKsize,     /* # of BYTES in subsequent ATAK envelope.
  287.                              If 0, then no ATAK data for this wave. */
  288.    RLSEsize,            /* # of BYTES in subsequent RLSE envelope
  289.                              If 0, then no RLSE envelope follows */
  290.  
  291.   /* The FATK and FRLS segments contain an EGPoint[] piece-wise
  292.      linear envelope for filtering purposes. This is included in
  293.      the hope that future Amiga audio will incorporate a VCF
  294.      (Voltage Controlled Filter). Until then, if you are doing any
  295.      non-realtime digital filtering, you could store info here. */
  296.  
  297.   sizeOfFATK,            /* # of BYTES in FATK segment */
  298.   sizeOfFRLS,            /* # of BYTES in FRLS segment */
  299.  
  300.   USERsize;        /*   # of BYTES in the following data
  301.                               segment (not including USERtype).
  302.                               If zero, then no user data */
  303.   UWORD  USERtype;     /* See explanation below. If USERsize
  304.                              = 0, then ignore this. */
  305.  
  306.  /* End of the waveHeader. */
  307.  
  308.  /* The data for any ATAK, RLSE, FATK, FRLS, USER, and the actual wave
  309.     data for wave #1 follows in this order:
  310.     Now list each EGPoint[] (if any) for the VCA's (Voltage Controlled Amp)
  311.     attack portion.
  312.     Now list each EGPoint[] for the VCA's (Voltage Controlled Amp)
  313.     release portion.
  314.     List EGPoints[] (if any) for FATK.
  315.     List EGPoints[] if any for FRLS */
  316.     Now include the user data here if there is any. Just pad it out
  317.     to an even number of bytes and have USERsize reflect that.
  318.     Finally, here is the actual sample data for the wave. The size (in BYTES)
  319.     of this data is WaveSize. It MUST be padded out to an even number of bytes. */
  320.  
  321.  } WaveFormInfo;
  322.  
  323.  /* END OF WAVE #1 */
  324.  
  325.  /* The waveHeader and data for the next wave would now follow. It is
  326.     the same form as the first wave */
  327.  
  328.  
  329.   In assembly,  the BODY chunk looks like this:
  330.  
  331.            CNOP 0,2
  332. BodyHEADER dc.b 'BODY'
  333. sizeOfBody dc.l  [total bytes in the BODY chunk not counting 8 byte header]
  334.  
  335.    ; Now for the first wave
  336. WaveSize       dc.l  ;[total # of BYTES in this wave (MUST be even)]
  337. MidiSampNum    dc.w  ;[from Midi Sample Dump]  ; ONLY USED for Midi Dumps
  338. LoopType       dc.b  ;[0 or 1]                 ; ONLY USED for Midi Dumps
  339. InsType        dc.b  0
  340. Period         dc.l  ;[period in nanoseconds at original pitch]
  341. Rate           dc.l  ;[# of samples per second at original pitch]
  342. LoopStart      dc.l    ;[an offset in BYTES (from the beginning of the
  343.                        ; of the wave) to where the looping
  344.                        ; portion of the wave begins.]
  345. LoopEnd        dc.l    ;[an offset in BYTES (from the beginning of the
  346.                        ; of the wave) to where the looping
  347.                        ; portion of the wave ends]
  348. RootNote       dc.b    ;[the Midi Note # that plays back original pitch]
  349. VelStart       dc.b    ;[0, 64, or 128]
  350. VelTable       dc.w    ;[first velocity offset]
  351.                dc.w    ;[second velocity offset]...etc
  352.                ds.w 14 ;...for a TOTAL of 16 velocity offsets
  353.  
  354. ATAKsize       dc.l  ;# of BYTES in subsequent ATAK envelope.
  355.                      ;If 0, then no ATAK data for this wave.
  356. RLSEsize       dc.l  ;# of BYTES in subsequent RLSE envelope
  357.                      ;If 0, then no RLSE data
  358. FATKsize       dc.l  ;# of BYTES in FATK segment
  359. FRLSsize       dc.l  ;# of BYTES in FRLS segment
  360. USERsize       dc.l  ;# of BYTES in the following User data
  361.                      ;segment (not including USERtype).
  362.                      ;If zero, then no user data
  363. USERtype       dc.w  ; See explanation below. If USERsize
  364.                   ; = 0, then ignore this.
  365.  
  366.   ;Now include the EGpoints[] (data) for the ATAK if any
  367.   ;Now the EGpoints for the RLSE
  368.   ;Now the EGpoints for the FATK
  369.   ;Now the EGpoints for the FLSR
  370.   ;Now include the user data here if there is any. Just pad
  371.   ;it out to an even number of bytes.
  372.   ;After the userdata (if any) is the actual sample data for
  373.   ;the wave. The size (in BYTES) of this segment is WaveSize.
  374.   ;It MUST be padded out to an even number of bytes.
  375.  
  376.   ; END OF WAVE #1
  377.  
  378.  
  379.       =============STRUCTURE OF AN INDIVIDUAL SAMPLE POINT=============
  380.  
  381.    Even though the next generation of computers will probably have 16 bit
  382. audio, and 8 bit sampling will quickly disappear, this spec has sizes expressed
  383. in BYTES. (ie LoopStart, WaveSize, etc.) This is because each successive
  384. address in RAM is a byte to the 68000, and so calculating address offsets
  385. will be much easier with all sizes in BYTES. The Midi sample dump, on the 
  386. other hand, has sizes expressed in WORDS. What this means is that if you
  387. have a 16 bit wave, for example, the WaveSize is the total number of BYTES,
  388. not WORDS, in the wave.
  389.   Also, there is no facility for storing a compression type. This is because
  390. sample data should be stored in linear format (as per the MIDI spec). Currently,
  391. all music samplers, regardless of their internal method of playing sample data
  392. must transmit and expect to receive sample dumps in a linear format. It is
  393. up to each device to translate the linear format into its own compression
  394. scheme. For example, if you are using an 8 bit compression scheme that yields
  395. a 14 bit linear range, you should convert each sample data BYTE to a decom-
  396. pressed linear WORD when you save a sound file. Set the MHDR's Format
  397. to 14. It is up to the application to do its own compression upon loading
  398. a file. The midi spec was set up this way because musical samplers need to
  399. pass sample data between each other, and computers (via a midi interface).
  400. Since there are almost as many data compression schemes on the market as
  401. there are musical products, it was decided that all samplers should expect
  402. data received over midi to be in LINEAR format. It seems logical to store it
  403. this way on disc as well. Therefore, any software program "need not know" how
  404. to decompress another software program's SAMP file. When 16 bit sampling is
  405. eventually implemented there won't be much need for compression on playback
  406. anyway. The continuation Flag solves the problem of disc storage as well.
  407.   Since the 68000 can only perform math on BYTES, WORDS, or LONGS, it has
  408. been decided that a sample point should be converted to one of these sizes
  409. when saved in SAMP as follows:
  410.  
  411.  ORIGINAL significant bits          SAMP sample point size
  412.  ­­­­­­­­­­­­­­­­­­­­­­­­­          ­­­­­­­­­­­­­­­­­­­­­­
  413.             8                               BYTE
  414.           9 to 16                           WORD
  415.           17 to 28                          LONG
  416.  
  417.   Furthermore, the significant bits should be left-justified since it is
  418. easier to perform math on the samples.
  419.  
  420.   So, for example, an 8 bit sample point (like 8SVX) would be saved as a
  421. BYTE with all 8 bits being significant. The MHDR's Format = 8. No
  422. conversion is necessary.
  423.  
  424.   A 12 bit sample point should be stored as a WORD with the significant bits
  425. being numbers 4 to 15. (i.e shift the 12-bit WORD 4 places to the left). Bits
  426. 0, 1, 2 and 3 may be zero (unless some 16-bit math was performed and you wish to
  427. save these results). The MHDR's Format = 12. In this way, the sample
  428. may be loaded and manipulated as a 16-bit wave, but when transmitted via
  429. midi, it can be converted back to 12 bits (rounded and shifted right by 4).
  430.  
  431.   A 16 bit sample point would be saved as a WORD with all 16 bits being
  432. significant. The MHDR's Format = 16. No conversion is necessary.
  433.  
  434.  
  435.           ============== The waveHeader explained ==============
  436.  
  437.    The WaveSize is, as stated, the number of BYTES in the wave's sample table.
  438. If your sample data consisted of the following 8 bit samples:
  439.  
  440.     BYTE  100,-90,80,-60,30,35,40,-30,-35,-40,00,12,12,10
  441.  
  442.  then WaveSize = 14. (PAD THE DATA OUT TO AN EVEN NUMBER OF BYTES!)
  443.  
  444.   The MidiSampNum is ONLY used to hold the sample number received from a MIDI
  445. Sample Dump. It has no bearing on where the wave should be placed in a SAMP
  446. file. Also, the wave numbers in the PlayMap are between 1 to 255, with 1 being
  447. the number of the first wave in the file. Remember that a wave number of 0 is
  448. reserved to mean "no wave to play back". Likewise, the LoopType is only used
  449. to hold info from a MIDI sample dump.
  450.  
  451.    The InsType is explained at the end of this document. Often it will be set
  452. to 0.
  453.  
  454.    The RootNote is the Midi Note number that will play the wave back at it's
  455. original, recorded pitch. For example, consider the following excerpt of a
  456. PlayMap:
  457.  
  458.   PlayMap  {2,0,0,4       /* Midi Note #0 channel assignment */
  459.             4,100,1,0     /* Midi Note #1    "        "  */
  460.             1,4,0,0       /* Midi Note #2    "        "  */
  461.             60,2,1,1...}  /* Midi Note #3    "        "  */
  462.  
  463.   Notice that Midi Notes 0, 1, and 2 are all set to play wave number 4 (on
  464. Amiga channels 3, 0, and 1 respectively). If we set wave 4's RootNote = 1,
  465. then receiving Midi Note number 1 would play back wave 4 (on Amiga channel 0)
  466. at it's original pitch. If we receive a Midi Note number 0, then wave 4 would
  467. be played back on channel 3) a half step lower than it's original pitch. If we
  468. receive Midi Note number 2, then wave 4 would be played (on channel 1) a half
  469. step higher than it's original pitch. If we receive Midi Note number 3, then
  470. wave 4 would not be played at all because it isn't specified in the PlayMap
  471. bytes for Midi Note number 3.
  472.  
  473.   The Rate is the number of samples per second of the original pitch.
  474. For example, if Rate = 20000, then to play the wave at it's original
  475. pitch, the sampling period would be:
  476.  
  477.      (1/20000)/.279365 = .000178977
  478.  
  479. #define AUDIO_HARDWARE_FUDGE .279365
  480.  
  481. where .279365 is the Amiga Fudge Factor (a hardware limitation). Since the
  482. amiga needs to see the period in terms of microseconds, move the decimal place
  483. to the right 6 places and our sampling period = 179 (rounded to an integer).
  484. In order to play the wave at higher or lower pitches, one would need to
  485. "transpose" this period value. By specifying a higher period value, the Amiga
  486. will play back the samples slower, and a lower pitch will be achieved. By
  487. specifying a lower period value, the amiga will play back the sample faster,
  488. and a higher pitch will be achieved. By specifying this exact period, the wave
  489. will be played back exactly "as it was recorded (sampled)". ("This period is
  490. JUST RIGHT!", exclaimed GoldiLocks.) Later, a method of transposing pitch will
  491. be shown using a "look up" table of periods. This should prove to be the
  492. fastest way to transpose pitch, though there is nothing in the SAMP format
  493. that compels you to do it this way.
  494.  
  495.   The LoopStart is a BYTE offset from the beginning of the wave to where
  496. the looping portion of the wave begins. For example, if SampleData points to
  497. the start of the wave, then SampleData + LoopStart is the start address
  498. of the looping portion. In 8SVX, the looping portion was referred to as
  499. repeatHiSamples. The data from the start of the wave up to the start of the
  500. looping portion is the oneShot portion of the wave. LoopEnd is a BYTE
  501. offset from the beginning of the wave to where the looping portion ends. This
  502. might be the very end of the wave in memory, or perhaps there might be still
  503. more data after this point. You can choose to ignore this "trailing" data and
  504. play back the two other portions of the wave just like an 8SVX file (except
  505. that there are no other interpolated octaves of this wave).
  506.  
  507.   VelTable contains 16 BYTE offsets from the beginning of the wave. Each
  508. successive value should be greater (or equal to) the preceding value. If
  509. VelStart = POSITIVE (64), then for each 8 increments in Midi Velocity
  510. above 0, you move UP in the table, add this offset to the wave's beginning
  511. address (start of oneShot), and start playback at that address. Here is a 
  512. table relating received midi note-on velocity vs. start playback address for
  513. POSITIVE VelStart. SamplePtr points to the beginning of the sample.
  514.  
  515.  If midi velocity = 0, then don't play a sample, this is a note off
  516.  If midi velocity = 1 to 7, then start play at SamplePtr + VelTable[0]
  517.  If midi velocity = 8 to 15, then start at SamplePtr + VelTable[1]
  518.  If midi velocity = 16 to 23, then start at SamplePtr + VelTable[2]
  519.  If midi velocity = 24 to 31, then start at SamplePtr + VelTable[3]
  520.  If midi velocity = 32 to 39, then start at SamplePtr + VelTable[4]
  521.  If midi velocity = 40 to 47, then start at SamplePtr + VelTable[5]
  522.  If midi velocity = 48 to 55, then start at SamplePtr + VelTable[6]
  523.  If midi velocity = 56 to 63, then start at SamplePtr + VelTable[7]
  524.  If midi velocity = 64 to 71, then start at SamplePtr + VelTable[8]
  525.  If midi velocity = 72 to 79, then start at SamplePtr + VelTable[9]
  526.  If midi velocity = 80 to 87, then start at SamplePtr + VelTable[10]
  527.  If midi velocity = 88 to 95, then start at SamplePtr + VelTable[11]
  528.  If midi velocity = 96 to 103, then start at SamplePtr + VelTable[12]
  529.  If midi velocity = 104 to 111, then start at SamplePtr + VelTable[13]
  530.  If midi velocity = 112 to 119, then start at SamplePtr + VelTable[14]
  531.  If midi velocity = 120 to 127, then start at SamplePtr + VelTable[15]
  532.  
  533. We don't want to specify a scale factor and use integer division to find the
  534. sample start. This would not only be slow, but also, it could never be certain
  535. that the resulting sample would be a zero crossing if the start point is calcu-
  536. lated "on the fly". The reason for having a table is so that the offsets can be
  537. be initially set on zero crossings via an editor. This way, no audio "clicks"
  538. guaranteed. This table should provide enough resolution.
  539.  
  540.    If VelStart = NEGATIVE (128), then for each 8 increments in midi
  541. velocity, you start from the END of VelTable, and work backwards. Here
  542. is a table for NEGATIVE velocity start.
  543.  
  544.  If midi velocity = 0, then don't play a sample, this is a note off
  545.  If midi velocity = 1 to 7, then start play at SamplePtr + VelTable[15]
  546.  If midi velocity = 8 to 15, then start at SamplePtr + VelTable[14]
  547.  If midi velocity = 16 to 23, then start at SamplePtr + VelTable[13]
  548.  If midi velocity = 24 to 31, then start at SamplePtr + VelTable[12]
  549.  If midi velocity = 32 to 39, then start at SamplePtr + VelTable[11]
  550.  If midi velocity = 40 to 47, then start at SamplePtr + VelTable[10]
  551.  If midi velocity = 48 to 55, then start at SamplePtr + VelTable[9]
  552.  If midi velocity = 56 to 63, then start at SamplePtr + VelTable[8]
  553.  If midi velocity = 64 to 71, then start at SamplePtr + VelTable[7]
  554.  If midi velocity = 72 to 81, then start at SamplePtr + VelTable[6]
  555.  If midi velocity = 80 to 87, then start at SamplePtr + VelTable[5]
  556.  If midi velocity = 88 to 95, then start at SamplePtr + VelTable[4]
  557.  If midi velocity = 96 to 103, then start at SamplePtr + VelTable[3]
  558.  If midi velocity = 104 to 111, then start at SamplePtr + VelTable[2]
  559.  If midi velocity = 112 to 119, then start at SamplePtr + VelTable[1]
  560.  If midi velocity = 120 to 127, then start at SamplePtr + VelTable[0]
  561.  
  562.  In essence, increasing midi velocity starts playback "farther into" the wave
  563. for POSITIVE VelStart. Increasing midi velocity "brings the start point
  564. back" toward the beginning of the wave for NEGATIVE VelStart.
  565.  
  566.  If VelStart is set to NONE (0), then the wave's playback start should
  567. not be affected by the table of offsets.
  568.  
  569.  What is the use of this feature? As an example, when a snare drum is hit with
  570. a soft volume, its initial attack is less pronounced than when it is struck
  571. hard. You might record a snare being hit hard. By setting VelStart to a
  572. NEGATIVE value and setting up the offsets in the Table, a lower midi velocity
  573. will "skip" the beginning samples and thereby tend to soften the initial
  574. attack. In this way, one wave yields a true representation of its instrument
  575. throughout its volume range. Furthermore, stringed and plucked instruments
  576. (violins, guitars, pianos, etc) exhibit different attacks at different
  577. volumes. VelStart makes these kinds of waves more realistic via a software
  578. implementation. Also, an application program can allow the user to enable/
  579. disable this feature. See the section "Making the Velocity Table" for info on
  580. how to best choose the 16 table values.
  581.  
  582.  
  583.         =========MIDI VELOCITY vs. AMIGA CHANNEL VOLUME============
  584.  
  585.  The legal range for Midi Velocity bytes is 0 to 127. (A midi velocity of 0
  586.  should ALWAYS be interpreted as a note off).
  587.  
  588.  The legal range for Amiga channel volume is 0 to 64. Since this is half of
  589.  the midi range, a received midi velocity should be divided by 2 and add 1
  590.  (but only AFTER checking for a received midi velocity of 0).
  591.  
  592.   An example of how to implement a received midi velocity in C:
  593.  
  594.   If ( ReceivedVelocity != 0 && ReceivedVelocity < 128 )
  595.   {   /* the velocity byte of a midi message */
  596.       If (velStart != 0)
  597.       {
  598.           tableEntry = ReceivedVelocity / 8;
  599.           If (velStart == 64)
  600.           {    /* Is it POSITIVE */
  601.                startOfWave = SamplePtr + velTable[tableEntry];
  602.                            /* ^where to find the sample start point */
  603.           }
  604.           If (velStart == 128)
  605.           {    /* Is it NEGATIVE */
  606.                startOfWave = SamplePtr + velTable[15 - tableEntry];
  607.           }
  608.           volume = (receivedVelocity/2 + 1;  /* playback volume */
  609.           /* Now playback the wave */
  610.       }
  611.   }
  612.  
  613.   In assembly,
  614.  
  615.   lea      SampleData,a0        ;the start addr of the sample data
  616.   moveq    #0,d0
  617.   move.b   ReceivedVelocity,d0  ;the velocity byte of a midi message
  618.   beq      A_NoteOff            ;If zero, branch to a routine to
  619.                                 ;process a note-off message.
  620.  
  621.   bmi      Illegal_Vol          ;exit if received velocity > 127
  622.   ;---Check for velocity start feature ON, and direction
  623.   move.b   VelStart,d1
  624.   beq.s    Volume               ;skip the velocity offset routine if 0
  625.   bmi.s    NegativeVel          ;is it NEGATIVE? (128)
  626.  
  627.   ;---Positive velocity offset
  628.   move.l   d0,d1                ;duplicate velocity
  629.   lsr.b    #3,d1                ;divide by 8
  630.   add.b    d1,d1                ;x 2 because we need to fetch a word
  631.   lea      VelTable,a1     ;start at table's HEAD
  632.   adda.l   d1,a1                ;go forward
  633.   move.w   (a1),d1              ;get the velocity offet
  634.   adda.l   d1,a0          ;where to start actual playback
  635.   bra.s    Volume
  636.  
  637. NegativeVel:
  638.   ;---Negative velocity offset
  639.   move.l   d0,d1                ;duplicate velocity
  640.   lsr.b    #3,d1                ;divide by 8
  641.   add.b    d1,d1                ;x 2 because we need to fetch a word
  642.   lea      VelTable+30,a1  ;start at table's END
  643.   suba.l   d1,a1                ;go backwards
  644.   move.w   (a1),d1              ;get the velocity offset
  645.   adda.l   d1,a0          ;where to start actual playback
  646.  
  647.   ;---Convert Midi velocity to an Amiga volume
  648. Volume  lsr.b    #1,d0          ;divide by 2
  649.         addq.b   #1,d0          ;an equivalent Amiga volume
  650.  
  651.  ;---Now a0 and d0 are the address of sample start, and volume
  652.  
  653.  
  654.      ================= AN EGpoint (envelope generator) ================
  655.  
  656.  A single EGpoint is a 6 byte structure as follows:
  657.  
  658. EGpoint1: dc.w ;[the duration in milliseconds]
  659.           dc.l ;[the volume factor - fixed point, 16 bits to the left of the
  660.                ;decimal point and 16 to the right.]
  661.  
  662.   The volume factor is a fixed point where 1.0 ($00010000) represents the
  663.   MAXIMUM volume possible. (i.e. No volume factor should exceed this value.)
  664.   The last EGpoint in the ATAK is always the sustain point. Each EG's volume
  665.   is determined from 0.0, not as a difference from the previous EG's volume.
  666.   I hope that this clears up the ambiguity in the original 8SVX document.
  667.   So, to recreate an amplifier envelope like this:
  668.  
  669.     /\
  670.    /  \____
  671.   /        \
  672.  /          \
  673.  
  674.  |  | |   |  |
  675.   1  2  3   4
  676.  
  677.   Stages 1, 2, and 3 would be in the ATAK data, like so:
  678.  
  679.   ;Stage 1
  680.   dc.w  100       ;take 100ms
  681.   dc.l  $00004000 ;go to this volume
  682.   dc.w  100
  683.   dc.l  $00008000
  684.   dc.w  100
  685.   dc.l  $0000C000
  686.   dc.w  100
  687.   dc.l  $00010000 ;the "peak" of our attack is full volume
  688.   ;Stage 2
  689.   dc.w  100
  690.   dc.l  $0000C000 ;back off to this level
  691.   dc.l  100
  692.   dc.l  $00008000 ;this is where we hold (SUSTAIN) until the note is turned
  693.                   ;off. (We are now holding at stage 3)
  694.  
  695.   Now the RLSE data would specify stage 4 as follows:
  696.   dc.w  100
  697.   dc.l  $00004000
  698.   dc.w  100
  699.   dc.l  $00000000 ;the volume is 0
  700.  
  701.  
  702.         ===============ADDITIONAL USER DATA SECTION=================
  703.  
  704.   There is a provision for storing user data for each wave. This is where an
  705. application can store Amiga hardware info, or other, application specific info.
  706. The waveHeader's USERtype tells what kind of data is stored. The current
  707. types are:
  708.  
  709. #define SPECIFIC 0
  710. #define VOLMOD   1
  711. #define PERMOD   2
  712. #define LOOPING  3
  713.  
  714.  SPECIFIC (0) - application specific data. It should be stored
  715.                 in a format that some application can immediately
  716.                 recognize. (i.e. a "format within" the SAMP format)
  717.                 If the USERtype is SPECIFIC, and an application
  718.                 doesn't find some sort of header that it can re-
  719.                 cognize, it should conclude that this data was
  720.                 put there by "someone else", and ignore the data.
  721.  
  722.  VOLMOD (1) -   This data is for volume modulation of an Amiga
  723.                 channel as described by the ADKCON register. This
  724.                 data will be sent to the modulator channel of the
  725.                 channel set to play the wave.
  726.  
  727.  PERMOD (2) -   This data is for period modulation of an Amiga
  728.                 channel as described by the ADKCON register. This
  729.                 data will be sent to the modulator channel of the
  730.                 channel set to play the wave.
  731.  
  732.  LOOPING (3) -  This contains more looping points for the sample.
  733.                 There are some samplers that allow more than just
  734.                 one loop (Casio products primarily). Additional
  735.                 looping info can be stored in this format:
  736.  
  737.                UWORD numOfLoops;  /* number of loop points to follow */
  738.  
  739.                ULONG StartLoop1,  /* BYTE offset from the beginning of
  740.                                     the sample to the start of loop1 */
  741.                EndLoop1,          /* BYTE offset from the beginning of
  742.                                     the sample to the end of loop1 */
  743.  
  744.                StartLoop2,        /* ...etc */
  745.  
  746.  
  747.           =========Converting Midi Sample Dump to SAMP=========
  748.  
  749.   SEMANTICS: When MIDI literature talks about a sample, usually it means a
  750. collection of many sample points that make up what we call "a wave".
  751. Therefore, a Midi Sample Dump sends all the sample data that makes up ONE
  752. wave. A SAMP file is designed to hold up to 255 of these waves (midi dumps).
  753.  
  754.   The Midi Sample Dump specifies playback rate only in terms of a sample
  755. PERIOD in nanoseconds. SAMP also expresses playback in terms of samples per
  756. second (frequency). The Amiga needs to see its period rounded to the nearest
  757. microsecond. If you take the sample period field of a Midi sample Dump (the
  758. 8th, 9th, and 10th bytes of the Dump Header LSB first) which we will call
  759. MidiSamplePer, and the Rate of a SAMP file, here is the relationship:
  760.  
  761.     Rate = (1/MidiSamplePer) x 10E9
  762.  
  763.   Also the number of samples (wave's length) in a Midi Sample Dump (the 11th,
  764. 12th, and 13th bytes of the Dump header) is expressed in WORDS. SAMP's
  765. WaveSize is expressed in the number of BYTES. (For the incredibly stupid),
  766. the relationship is:
  767.  
  768.    WaveSize = MidiSampleLength x 2
  769.  
  770.   A Midi sample dump's LoopStart point and LoopEnd point are also in WORDS as
  771. versus the SAMP equivalents expressed in BYTES.
  772.  
  773.    A Midi sample dump's sample number can be 0 to 65535. A SAMP file can hold
  774. up to 255 waves, and their numbers in the playmap must be 1 to 255. (A single,
  775. Midi Sample Dump only sends info on one wave.) When recieving a Midi Sample
  776. Dump, just store the sample number (5th and 6th bytes of the Dump Header LSB
  777. first) in SAMP's MidiSampNum field. Then forget about this number until you
  778. need to send the wave back to the Midi instrument from whence it came.
  779.  
  780.   A Midi Dump's loop type can be forward, or forward/backward. Amiga hardware
  781. supports forward only. You should store the Midi Dump's LoopType byte here,
  782. but ignore it otherwise until/unless Amiga hardware supports "reading audio
  783. data" in various ways. If so, then the looptype is as follows:
  784.  
  785.     forward = 0, backward/forward = 1
  786.  
  787.   A Midi Dump's sample format byte is the same as SAMP's.
  788.  
  789.  
  790.   ===================== INTERPRETING THE PLAYMODE ==========================
  791.  
  792.   PlayMode specifies how the bytes in the PlayMap are to be interpreted.
  793.   Remember that a PlayMap byte of 0 means "No Wave to Play".
  794.  
  795. #define INDEPENDANT 0
  796. #define MULTI       1
  797. #define STEREO      2
  798. #define PAN         3
  799.  
  800.   PlayMode types:
  801.  
  802.  INDEPENDANT (0) - The wave #s for a midi note are to be output on
  803.                    Amiga audio channels 0, 1, 2, and 3 respectively.
  804.                    If the NumOfChans is < 4, then only use that many channels.
  805.  
  806.  MULTI       (1) - The first wave # (first of the PlayMap bytes) for a
  807.                    midi note is to be output on any free channel. The other
  808.                    wave numbers are ignored. If all four channels are in
  809.                    play, the application can decide whether to "steal" a
  810.                    channel.
  811.  
  812.  STEREO     (2) -  The first wave # (first of the PlayMap bytes) is to be
  813.                    output of the Left stereo jack (channel 1 or 3) and if
  814.                    there is a second wave number (the second of the PlayMap
  815.                    bytes), it is to be output the Right jack (channel 2 or 4).
  816.                    The other wave numbers are ignored.
  817.  
  818.  PAN        (3) -  This is just like STEREO except that the volume of wave 1
  819.                    should start at its initial volume (midi velocity) and
  820.                    fade to 0. At the same rate, wave 2 should start at 0
  821.                    volume and rise to wave #1's initial level. The net
  822.                    effect is that the waves "cross" from Left to Right in
  823.                    the stereo field. This is most effective when the wave
  824.                    numbers are the same. (ie the same wave) The application
  825.                    program should set the rate. Also, the application can
  826.                    reverse the stereo direction (ie Right to Left fade).
  827.  
  828.   The most important wave # to be played back by a midi note should be the
  829. first of the PlayMap bytes. If the NumOfChans > 1, the second PlayMap byte
  830. should be a defined wave number as well (even if it is deliberately set to the
  831. same value as the first byte). This insures that all 4 PlayModes will have some
  832. effect on a given SAMP file. Also, an application should allow the user to
  833. change the PlayMode at will. The PlayMode stored in the SAMP file is only a
  834. default or initial set-up condition.
  835.  
  836.  
  837.   =================== MAKING A TRANSPOSE TABLE =====================
  838.  
  839.  In order to allow a wave to playback over a range of musical notes, (+/-
  840. semitones), its playback rate must be raised or lowered by a set amount.
  841. From one semitone to the next, this set amount is by a factor of the 12th
  842. root of 2 (assuming a western, equal-tempered scale). Here is a table that
  843. shows what factor would need to be multiplied by the sampling rate in order
  844. to transpose the wave's pitch.
  845.  
  846.   Pitch in relation to the Root     Multiply Rate by this amount
  847.  -------------------------------   ------------------------------
  848.    DOWN 6     semitones              0.5
  849.    DOWN 5 1/2 semitones              0.529731547
  850.    DOWN 5     semitones              0.561231024
  851.    DOWN 4 1/2 semitones              0.594603557
  852.    DOWN 4     semitones              0.629960525
  853.    DOWN 3 1/2 semitones              0.667419927
  854.    DOWN 3     semitones              0.707106781
  855.    DOWN 2 1/2 semitones              0.749153538
  856.    DOWN 2     semitones              0.793700526
  857.    DOWN 1 1/2 semitones              0.840896415
  858.    DOWN 1     semitones              0.890898718
  859.    DOWN 1/2   semitone               0.943874312
  860. ORIGINAL_PITCH                       1.0           /* rootnote's pitch */
  861.    UP   1/2   semitone               1.059463094
  862.    UP   1     semitones              1.122562048
  863.    UP   1 1/2 semitones              1.189207115
  864.    UP   2     semitones              1.259921050
  865.    UP   2 1/2 semitones              1.334839854
  866.    UP   3     semitones              1.414213562
  867.    UP   3 1/2 semitones              1.498307077
  868.    UP   4     semitones              1.587401052
  869.    UP   4 1/2 semitones              1.681792830
  870.    UP   5     semitones              1.781797436
  871.    UP   5 1/2 semitones              1.887748625
  872.    UP   6     semitones              2
  873.  
  874.   For example, if the wave's Rate is 18000 hz, and you wish to play
  875. the wave UP 1 semitone, then the playback rate is:
  876.  
  877.    18000 x 1.122562048 = 20206.11686 hz
  878.  
  879.   The sampling period for the Amiga is therefore:
  880.  
  881.      (1/20206.11686)/.279365 = .000177151
  882.  
  883.  and to send it to the Audio Device, it is rounded and expressed in micro-
  884. seconds: 177
  885.  
  886.   Obviously, this involves floating point math which can be time consuming
  887. and impractical for outputing sound in real-time. A better method is to con-
  888. struct a transpose table that contains the actual periods already calculated
  889. for every semitone. The drawback of this method is that you need a table for
  890. EVERY DIFFERENT Rate in the SAMP file. If all the Rates in the
  891. file happened to be the same, then only one table would be needed. Let's
  892. assume that this is the case, and that the Rate = 18000 hz. Here is a
  893. table containing enough entries to transpose the waves +/- 6 semitones.
  894.  
  895.   Pitch in relation to the Root     The Amiga Period (assuming rate = 18000 hz)
  896.  -------------------------------   ------------------------------
  897. Transposition_table[TRANS_TABLE_SIZE]={
  898. /* DOWN 6     semitones  */            398,
  899. /* DOWN 5 1/2 semitones  */            375,
  900. /* DOWN 5     semitones  */            354,
  901. /* DOWN 4 1/2 semitones  */            334,
  902. /* DOWN 4     semitones  */            316,
  903. /* DOWN 3 1/2 semitones  */            298,
  904. /* DOWN 3     semitones  */            281,
  905. /* DOWN 2 1/2 semitones  */            265,
  906. /* DOWN 2     semitones  */            251,
  907. /* DOWN 1 1/2 semitones  */            236,
  908. /* DOWN 1     semitones  */            223,
  909. /* DOWN 1/2   semitone   */            211,
  910. /* ORIGINAL_PITCH        */            199,      /* rootnote's pitch */
  911. /* UP   1/2   semitone   */            187,
  912. /* UP   1     semitones  */            177,
  913. /* UP   1 1/2 semitones  */            167,
  914. /* UP   2     semitones  */            157,
  915. /* UP   2 1/2 semitones  */            148,
  916. /* UP   3     semitones  */            141,
  917. /* UP   3 1/2 semitones  */            133,
  918.  /* Since the minimum Amiga period = 127 the following
  919.     are actually out of range. */
  920. /* UP   4     semitones  */            125,
  921. /* UP   4 1/2 semitones  */            118,
  922. /* UP   5     semitones  */            112,
  923. /* UP   5 1/2 semitones  */            105,
  924. /* UP   6     semitones  */            99   };
  925.  
  926.  
  927.   Let's assume that (according to the PlayMap) midi note #40 is set to play
  928. wave number 3. Upon examining wave 3's structure, we discover that the
  929. Rate = 18000, and the RootNote = 38. Here is how the Amiga sampling
  930. period is calulated using the above 18000hz "transpose chart" in C:
  931.   /* MidiNoteNumber is the received midi note's number (here 40) */
  932.  
  933.   #define ORIGINAL_PITCH     TRANS_TABLE_SIZE/2 + 1
  934. /* TRANS_TABLE_SIZE is the number of entries in the transposition table
  935.    (dynamic, ie this can change with the application) */
  936.  
  937.   transposeAmount = (LONG) (MidiNoteNumber - rootNote); /* make it a SIGNED LONG */
  938.   amigaPeriod     = Transposition_table[ORIGINAL_PITCH + transposeAmount];
  939.  
  940.  
  941.   In assembly, the 18000hz transpose chart and above example would be:
  942.  
  943. Table       dc.w  398
  944.             dc.w  375
  945.             dc.w  354
  946.             dc.w  334
  947.             dc.w  316
  948.             dc.w  298
  949.             dc.w  281
  950.             dc.w  265
  951.             dc.w  251
  952.             dc.w  236
  953.             dc.w  223
  954.             dc.w  211
  955. ORIGINAL_PITCH  dc.w  199   ; rootnote's pitch
  956.             dc.w  187
  957.             dc.w  177
  958.             dc.w  167
  959.             dc.w  157
  960.             dc.w  148
  961.             dc.w  141
  962.             dc.w  133
  963.  ; Since the minimum Amiga period = 127, the following
  964.  ; are actually out of range.
  965.             dc.w  125
  966.             dc.w  118
  967.             dc.w  112
  968.             dc.w  105
  969.             dc.w  99
  970.  
  971.   lea     ORIGINAL_PITCH,a0
  972.   move.b  MidiNoteNumber,d0  ;the received note number
  973.   sub.b   RootNote,d0        ;subtract the wave's root note
  974.   ext.w   d0
  975.   ext.l   d0                 ;make it a signed LONG
  976.   add.l   d0,d0              ;x 2 in order to fetch a WORD
  977.   adda.l  d0,a0
  978.   move.w  (a0),d0            ;the Amiga Period (WORD)
  979.  
  980.   Note that these examples don't check to see if the transpose amount is
  981. beyond the number of entries in the transpose table. Nor do they check if
  982. the periods in the table are out of range of the Amiga hardware.
  983.  
  984.  
  985.     ===================== MAKING THE VELOCITY TABLE ======================
  986.  
  987.   The 16 entries in the velocity table should be within the oneShot portion of
  988. the sample (ie not in the looping portion). THe first offset, VelTable[0]
  989. should be set to zero (in order to play back from the beginning of the data).
  990. The subsequent values should be increasing numbers. If you are using a graphic
  991. editor, try choosing offsets that will keep you within the initial attack
  992. portion of the wave. In practice, these values will be relatively close
  993. together within the wave. Always set the offsets so that when they are added
  994. to the sample start point, the resulting address points to a sample value of
  995. zero (a zero crossing point). This will eliminate pops and clicks at the
  996. beginning of the playback.
  997.  
  998.   In addition, the start of the wave should be on a sample with a value of
  999. zero. The last sample of the oneShot portion and the first sample of the
  1000. looping portion should be approximately equal, (or zero points). The same is
  1001. true of the first and last samples of the looping portion. Finally, try to
  1002. keep the slopes of the end of the oneShot, the beginning of the looping, and
  1003. the end of the looping section, approximately equal. All this will eliminate
  1004. noise on the audio output and provide "seamless" looping.
  1005.  
  1006.  
  1007.   ======================== THE INSTRUMENT TYPE ==========================
  1008.  
  1009.   Many SMUS players search for certain instruments by name. Not only is this
  1010. slow (comparing strings), but if the exact name can't be found, then it is
  1011. very difficult and time-consuming to search for a suitable replacement. For
  1012. this reason, many SMUS players resort to "default" instruments even if these
  1013. are nothing like the desired instruments. The InsType byte in each
  1014. waveHeader is meant to be a numeric code which will tell an SMUS player
  1015. exactly what the instrument is. In this way, the SMUS player can search for
  1016. the correct "type" of instrument if it can't find the desired name. The type
  1017. byte is divided into 2 nibbles (4 bits for you C programmers) with the low
  1018. 4 bits representing the instrument "family" as follows:
  1019.  
  1020.  1 = STRING, 2 = WOODWIND, 3 = KEYBOARD, 4 = GUITAR, 5 = VOICE, 6 = DRUM1,
  1021.  7 = DRUM2,  8 = PERCUSSION1, 9 = BRASS1, A = BRASS2, B = CYMBAL, C = EFFECT1,
  1022.  D = EFFECT2, E = SYNTH, F is undefined at this time
  1023.  
  1024.  Now, the high nibble describes the particular type within that family.
  1025.  
  1026.  For the STRING family, the high nibble is as follows:
  1027.  
  1028.  1 = VIOLIN BOW, 2 = VIOLIN PLUCK, 3 = VIOLIN GLISSANDO, 4 = VIOLIN TREMULO,
  1029.  5 = VIOLA BOW, 6 = VIOLA PLUCK, 7 = VIOLA GLIS, 8 = VIOLA TREM, 9 = CELLO
  1030.  BOW, A = CELLO PLUCK, B = CELLO GLIS, C = CELLO TREM, D = BASS BOW, E =
  1031.  BASS PLUCK (jazz bass), F = BASS TREM
  1032.  
  1033.  For the BRASS1 family, the high nibble is as follows:
  1034.  
  1035.  1 = BARITONE SAX, 2 = BARI GROWL, 3 = TENOR SAX, 4 = TENOR GROWL, 5 = ALTO
  1036.  SAX, 6 = ALTO GROWL, 7 = SOPRANO SAX, 8 = SOPRANO GROWL, 9 = TRUMPET, A =
  1037.  MUTED TRUMPET, B = TRUMPET DROP, C = TROMBONE, D = TROMBONE SLIDE, E =
  1038.  TROMBONE MUTE
  1039.  
  1040.  For the BRASS2 family, the high nibble is as follows:
  1041.  
  1042.  1 = FRENCH HORN, 2 = TUBA, 3 = FLUGAL HORN, 4 = ENGLISH HORN
  1043.  
  1044.  For the WOODWIND family, the high nibble is as follows:
  1045.  
  1046.  1 = CLARINET, 2 = FLUTE, 3 = PAN FLUTE, 4 = OBOE, 5 = PICCOLO, 6 = RECORDER,
  1047.  7 = BASSOON, 8 = BASS CLARINET, 9 = HARMONICA
  1048.  
  1049.  For the KEYBOARD family, the high nibble is as follows:
  1050.  
  1051.  1 = GRAND PIANO, 2 = ELEC. PIANO, 3 = HONKYTONK PIANO, 4 = TOY PIANO, 5 =
  1052.  HARPSICHORD, 6 = CLAVINET, 7 = PIPE ORGAN, 8 = HAMMOND B-3, 9 = FARFISA
  1053.  ORGAN, A = HARP
  1054.  
  1055.  For the DRUM1 family, the high nibble is as follows:
  1056.  
  1057.  1 = KICK, 2 = SNARE, 3 = TOM, 4 = TIMBALES, 5 = CONGA HIT, 6 = CONGA SLAP,
  1058.  7 = BRUSH SNARE, 8 = ELEC SNARE, 9 = ELEC KICK, A = ELEC TOM, B = RIMSHOT,
  1059.  C = CROSS STICK, D = BONGO, E = STEEL DRUM, F = DOUBLE TOM
  1060.  
  1061.  For the DRUM2 family, the high nibble is as follows:
  1062.  
  1063.  1 = TIMPANI, 2 = TIMPANI ROLL, 3 = LOG DRUM
  1064.  
  1065.  For the PERCUSSION1 family, the high nibble is as follows:
  1066.  
  1067.  1 = BLOCK, 2 = COWBELL, 3 = TRIANGLE, 4 = TAMBOURINE, 5 = WHISTLE, 6 =
  1068.  MARACAS, 7 = BELL, 8 = VIBES, 9 = MARIMBA, A = XYLOPHONE, B = TUBULAR BELLS,
  1069.  C = GLOCKENSPEIL
  1070.  
  1071.  For the CYMBAL family, the high nibble is as follows:
  1072.  
  1073.  1 = CLOSED HIHAT, 2 = OPEN HIHAT, 3 = STEP HIHAT, 4 = RIDE, 5 = BELL CYMBAL,
  1074.  6 = CRASH, 7 = CHOKE CRASH, 8 = GONG, 9 = BELL TREE, A = CYMBAL ROLL
  1075.  
  1076.  For the GUITAR family, the high nibble is as follows:
  1077.  
  1078.  1 = ELECTRIC, 2 = MUTED ELECTRIC, 3 = DISTORTED, 4 = ACOUSTIC, 5 = 12-STRING,
  1079.  6 = NYLON STRING, 7 = POWER CHORD, 8 = HARMONICS, 9 = CHORD STRUM, A = BANJO,
  1080.  B = ELEC. BASS, C = SLAPPED BASS, D = POPPED BASS, E = SITAR, F = MANDOLIN
  1081.  (Note that an acoustic picked bass is found in the STRINGS - Bass Pluck)
  1082.  
  1083.  For the VOICE family, the high nibble is as follows:
  1084.  
  1085.  1 = MALE AHH, 2 = FEMALE AHH, 3 = MALE OOO, 4 = FEMALE OOO, 5 = FEMALE
  1086.  BREATHY, 6 = LAUGH, 7 = WHISTLE
  1087.  
  1088.  For the EFFECTS1 family, the high nibble is as follows:
  1089.  
  1090.  1 = EXPLOSION, 2 = GUNSHOT, 3 = CREAKING DOOR OPEN, 4 = DOOR SLAM, 5 = DOOR
  1091.  CLOSE, 6 = SPACEGUN, 7 = JET ENGINE, 8 = PROPELLER, 9 = HELOCOPTER, A =
  1092.  BROKEN GLASS, B = THUNDER, C = RAIN, D = BIRDS, E = JUNGLE NOISES, F =
  1093.  FOOTSTEP
  1094.  
  1095.  For the EFFECTS2 family, the high nibble is as follows:
  1096.  
  1097.  1 = MACHINE GUN, 2 = TELEPHONE, 3 = DOG BARK, 4 = DOG GROWL, 5 = BOAT
  1098.  WHISTLE, 6 = OCEAN, 7 = WIND, 8 = CROWD BOOS, 9 = APPLAUSE, A = ROARING
  1099.  CROWDS, B = SCREAM, C = SWORD CLASH, D = AVALANCE, E = BOUNCING BALL,
  1100.  F = BALL AGAINST BAT OR CLUB
  1101.  
  1102.  For the SYNTH family, the high nibble is as follows:
  1103.  
  1104.  1 = STRINGS, 2 = SQUARE, 3 = SAWTOOTH, 4 = TRIANGLE, 5 = SINE, 6 = NOISE
  1105.  
  1106.   So, for example if a wave's type byte was 0x26, this would be a SNARE DRUM.
  1107. If a wave's type byte is 0, then this means "UNKNOWN" instrument.
  1108.  
  1109.  
  1110.   ===================== THE ORDER OF THE CHUNKS =========================
  1111.  
  1112.  The SAMP header obviously must be first in the file, followed by the MHDR
  1113. chunk. After this, the ANNO, (c), AUTH and NAME chunks may follow in any
  1114. order, though none of these need appear in the file at all. The BODY chunk
  1115. must be last.
  1116.  
  1117.  
  1118.         ================= FILENAME CONVENTIONS =================
  1119.  
  1120.    For when it becomes necessary to split a SAMP file between floppies using
  1121. the Continuation feature, the filenames should be related. The method is the
  1122. following:
  1123.  
  1124.    The "root" file has the name that the user chose to save under. Subsequent
  1125. files have an ascii number appended to the name to indicate what sublevel the
  1126. file is in. In this way, a program can reload the files in the proper order.
  1127.  
  1128.    For example, if a user saved a file called "Gurgle", the first continuation
  1129. file should be named "Gurgle1", etc.
  1130.  
  1131.  
  1132.   ============ WHY DOES ANYONE NEED SUCH A COMPLICATED FILE? ==============
  1133.                  (or "What's wrong with 8SVX anyway?")
  1134.  
  1135.   In a nutshell, 8SVX is not adequate for professional music sampling. First
  1136. of all, it is nearly impossible to use multi-sampling (utilizing several,
  1137. different samples of any instrument throughout its musical range). This very
  1138. reason alone makes it impossible to realistically reproduce a musical in-
  1139. strument, as none in existance (aside from an electronic organ) uses inter-
  1140. polations of a single wave to create its musical note range.
  1141.   Also, stretching a sample out over an entire octave range does grotesque
  1142. (and VERY unmusical) things to such elements as the overtone structure,
  1143. wind/percussive noises, the instrument's amplitude envelope, etc. The 8SVX
  1144. format is designed to stretch the playback in exactly this manner.
  1145.   8SVX ignores MIDI which is the de facto standard of musical data transmission.
  1146.   8SVX does not allow storing data for features that are commonplace to pro-
  1147. fessional music samplers. Such features are: velocity sample start, separate
  1148. filter and envelopes for each sample, separate sampling rates, and various
  1149. playback modes like stereo sampling and panning.
  1150.   SAMP attempts to remedy all of these problems with a format that can be
  1151. used by a program that simulates these professional features in software. The
  1152. format was inspired by the capabilities of the following musical products:
  1153.  
  1154.   EMU's                 EMAX, EMULATOR
  1155.   SEQUENTIAL CIRCUIT's  PROPHET 2000, STUDIO 440
  1156.   ENSONIQ's             MIRAGE
  1157.   CASIO's               FZ-1
  1158.   OBERHEIM's            DPX
  1159.   YAMAHA                TX series
  1160.  
  1161.    So why does the Amiga need the SAMP format? Because professional musician's
  1162. are buying computers. With the firm establishment of MIDI, musician's are
  1163. buying and using a variety of sequencers, patch editors, and scoring programs.
  1164. It is now common knowledge amoung professional musicians that the Amiga
  1165. lags far behind IBM clones, Macintosh, and Atari ST computers in both music
  1166. software and hardware support. Both Commodore and the current crop of short-
  1167. sighted 3rd party Amiga developers are pigeon-holing the Amiga as "a video
  1168. computer". It is important for music software to exploit whatever capabili-
  1169. ties the Amiga offers before the paint and animation programs, genlocks,
  1170. frame-grabbers, and video breadboxes are the only applications selling
  1171. for the Amiga. Hopefully, this format, with the SAMP disk I/O library will
  1172. make it possible for Amiga software to attain the level of professionalism
  1173. that the other machines now boast, and the Amiga lacks.
  1174.